﻿Public Class MainViewModel
    Inherits ViewModelBase

#Region "Events"
    ' Insert Event Declarations Here
#End Region

#Region "Properties"
#Region "Constants"
    ' Insert Constant Declarations Here
#End Region

    Protected Property Project As IRegexProject

    Private _regExPattern As String = ""
    Friend Const PROPERTY_REGEX_PATTERN As String = "RegexPattern"
    Public Property RegexPattern() As String
        Get
            Return _regExPattern
        End Get
        Set(ByVal value As String)
            If _regExPattern <> value Then
                _regExPattern = value
                MyBase.OnPropertyChanged()
            End If
        End Set
    End Property

    Private Const PROPERTY_LITERAL_TEXT_INPUT As String = "LiteralTextInput"
    Private _literalTextInput As LiteralTextInputViewModel
    Public Property LiteralTextInput() As LiteralTextInputViewModel
        Get
            Return _literalTextInput
        End Get
        Private Set(ByVal value As LiteralTextInputViewModel)
            If _literalTextInput IsNot value Then
                _literalTextInput = value
                MyBase.OnPropertyChanged()
            End If
        End Set
    End Property

    Private Const PROPERTY_MULTIPLE_FILES_INPUT As String = "MultipleFilesInput"
    Private _multipleFilesInput As MultipleFilesInputViewModel
    Public Property MultipleFilesInput() As MultipleFilesInputViewModel
        Get
            Return _multipleFilesInput
        End Get
        Private Set(ByVal value As MultipleFilesInputViewModel)
            If _multipleFilesInput IsNot value Then
                _multipleFilesInput = value
                MyBase.OnPropertyChanged()
            End If
        End Set
    End Property

    Private Const PROPERTY_DIRECTORY_INPUT As String = "DirectoryInput"
    Private _directoryInput As DirectoryInputViewModel
    Public Property DirectoryInput() As DirectoryInputViewModel
        Get
            Return _directoryInput
        End Get
        Private Set(ByVal value As DirectoryInputViewModel)
            If _directoryInput IsNot value Then
                _directoryInput = value
                MyBase.OnPropertyChanged()
            End If
        End Set
    End Property

    Private Const PROPERTY_REGISTRY_INPUT As String = "RegistryInput"
    Private _registryInput As RegistryInputViewModel
    Public Property RegistryInput() As RegistryInputViewModel
        Get
            Return _registryInput
        End Get
        Private Set(ByVal value As RegistryInputViewModel)
            If _registryInput IsNot value Then
                _registryInput = value
                MyBase.OnPropertyChanged()
            End If
        End Set
    End Property

    Private ReadOnly _inputViewModels() As RegexInputViewModelBase
    <PropertyDependency(PROPERTY_DIRECTORY_INPUT)>
    <PropertyDependency(PROPERTY_LITERAL_TEXT_INPUT)>
    <PropertyDependency(PROPERTY_MULTIPLE_FILES_INPUT)>
    <PropertyDependency(PROPERTY_REGISTRY_INPUT)>
    Public ReadOnly Property InputViewModels As IEnumerable(Of RegexInputViewModelBase)
        Get
            Return New RegexInputViewModelBase() {
                Me.LiteralTextInput,
                Me.MultipleFilesInput,
                Me.DirectoryInput,
                Me.RegistryInput
            }
        End Get
    End Property

    Friend Const PROPERTY_SELECTED_INPUT_VIEW_MODEL As String = "SelectedInputViewModel"
    Private _selectedInputViewModel As RegexInputViewModelBase
    Public Property SelectedInputViewModel As RegexInputViewModelBase
        Get
            Return _selectedInputViewModel
        End Get
        Set(value As RegexInputViewModelBase)
            If _selectedInputViewModel IsNot value Then
                _selectedInputViewModel = value
                MyBase.OnPropertyChanged(PROPERTY_SELECTED_INPUT_VIEW_MODEL)
            End If
        End Set
    End Property

    Public ReadOnly Property RegexHistory As Stack(Of Tuple(Of String, RegexOptions))
        Get
            Return Me.Project.RegexHistory
        End Get
    End Property

#Region "Regex Options"
    Private _RegexOptions As RegexOptions
    Friend Const PROPERTY_REGEX_OPTIONS As String = "RegexOptions"
    Public Property RegexOptions() As RegexOptions
        Get
            Return _RegexOptions
        End Get
        Private Set(ByVal value As RegexOptions)
            If value <> _RegexOptions Then
                Dim l_ecmaChecked = Not (_RegexOptions And RegexOptions.ECMAScript) AndAlso (value And RegexOptions.ECMAScript)

                If l_ecmaChecked Then
                    value = value And (RegexOptions.ECMAScript Or RegexOptions.IgnoreCase Or RegexOptions.Multiline Or RegexOptions.Compiled)
                End If

                _RegexOptions = value
                MyBase.OnPropertyChanged()
            End If
        End Set
    End Property

    <PropertyDependency(PROPERTY_REGEX_OPTIONS)>
    Public Property IsRegexECMAScriptEnabled As Boolean
        Get
            Return Me.RegexOptions And RegexOptions.ECMAScript
        End Get
        Set(value As Boolean)
            ToggleRegexOption(RegexOptions.ECMAScript, value)
        End Set
    End Property

    <PropertyDependency(PROPERTY_REGEX_OPTIONS)>
    Public Property IsRegexIgnoreCaseEnabled As Boolean
        Get
            Return Me.RegexOptions And RegexOptions.IgnoreCase
        End Get
        Set(value As Boolean)
            ToggleRegexOption(RegexOptions.IgnoreCase, value)
        End Set
    End Property

    <PropertyDependency(PROPERTY_REGEX_OPTIONS)>
    Public Property IsRegexMultilineEnabled As Boolean
        Get
            Return Me.RegexOptions And RegexOptions.Multiline
        End Get
        Set(value As Boolean)
            ToggleRegexOption(RegexOptions.Multiline, value)
        End Set
    End Property

    <PropertyDependency(PROPERTY_REGEX_OPTIONS)>
    Public Property IsRegexCompiledEnabled As Boolean
        Get
            Return Me.RegexOptions And RegexOptions.Compiled
        End Get
        Set(value As Boolean)
            ToggleRegexOption(RegexOptions.Compiled, value)
        End Set
    End Property

    <PropertyDependency(PROPERTY_REGEX_OPTIONS)>
    Public Property IsRegexExplicitCaptureEnabled As Boolean
        Get
            Return Me.RegexOptions And RegexOptions.ExplicitCapture
        End Get
        Set(value As Boolean)
            ToggleRegexOption(RegexOptions.ExplicitCapture, value)
        End Set
    End Property

    <PropertyDependency(PROPERTY_REGEX_OPTIONS)>
    Public Property IsRegexSinglelineEnabled As Boolean
        Get
            Return Me.RegexOptions And RegexOptions.Singleline
        End Get
        Set(value As Boolean)
            ToggleRegexOption(RegexOptions.Singleline, value)
        End Set
    End Property

    <PropertyDependency(PROPERTY_REGEX_OPTIONS)>
    Public Property IsRegexIgnorePatternWhitespaceEnabled As Boolean
        Get
            Return Me.RegexOptions And RegexOptions.IgnorePatternWhitespace
        End Get
        Set(value As Boolean)
            ToggleRegexOption(RegexOptions.IgnorePatternWhitespace, value)
        End Set
    End Property

    <PropertyDependency(PROPERTY_REGEX_OPTIONS)>
    Public Property IsRegexRightToLeftEnabled As Boolean
        Get
            Return Me.RegexOptions And RegexOptions.RightToLeft
        End Get
        Set(value As Boolean)
            ToggleRegexOption(RegexOptions.RightToLeft, value)
        End Set
    End Property

    <PropertyDependency(PROPERTY_REGEX_OPTIONS)>
    Public Property IsRegexCultureInvariantEnabled As Boolean
        Get
            Return Me.RegexOptions And RegexOptions.CultureInvariant
        End Get
        Set(value As Boolean)
            ToggleRegexOption(RegexOptions.CultureInvariant, value)
        End Set
    End Property
#End Region

#End Region

#Region "Constructors"
    Public Sub New(viewNavigator As IViewNavigator)
        MyBase.New(viewNavigator)

        Me.Project = RegExUtility.Model.CreateRegexProject()

        AddHandler Me.Project.PropertyChanged, AddressOf Project_PropertyChanged

        Me.LiteralTextInput = New LiteralTextInputViewModel(Me.Project.LiteralTextInput, Me, viewNavigator)
        Me.MultipleFilesInput = New MultipleFilesInputViewModel(Me.Project.MultipleFilesInput, Me, viewNavigator)
        Me.DirectoryInput = New DirectoryInputViewModel(Me.Project.DirectoryInput, Me, viewNavigator)
        Me.RegistryInput = New RegistryInputViewModel(Me.Project.RegistryInput, Me, viewNavigator)

        MyBase.AddCommand(commandName:="Open",
                          executeCallback:=AddressOf OpenRegex)

        MyBase.AddCommand(commandName:="Save",
                          executeCallback:=AddressOf SaveRegex)

        MyBase.AddCommand(commandName:="Exit",
                          executeCallback:=AddressOf ExitApplication)

        MyBase.AddCommand(commandName:="FormatRegex",
                          executeCallback:=AddressOf FormatRegex)
    End Sub
#End Region

#Region "Methods"
    Public Function CreateRegex(requestor As String) As Regex
        Me.Project.RecordRegex(Me.RegexPattern, Me.RegexOptions)
        Return New Regex(If(Me.RegexPattern, ""), Me.RegexOptions)
    End Function

    Private Sub ToggleRegexOption([option] As RegexOptions, value As Boolean)
        If value Then
            If Not (Me.RegexOptions And [option]) Then Me.RegexOptions = Me.RegexOptions Or [option]
        Else
            If (Me.RegexOptions And [option]) Then Me.RegexOptions = Me.RegexOptions And Not [option]
        End If
    End Sub

    Private Sub OpenRegex()

    End Sub

    Private Sub SaveRegex()

    End Sub

    Private Sub ExitApplication()
        Environment.Exit(0)
    End Sub

    Private Sub FormatRegex(parameter As String)
        ' Before formatting the regular expression, record it to history, otherwise 
        ' the formatter will use the previous regex
        CreateRegex("Regex Formatter")
        ' Record the code in the clipboard
        Dim l_formatter As IRegexFormatter
        Select Case parameter
            Case "CSharp"
                l_formatter = RegexFormatters.CSharp
            Case "VB"
                l_formatter = RegexFormatters.VB
            Case Else
                l_formatter = Nothing
        End Select
        If l_formatter IsNot Nothing Then My.Computer.Clipboard.SetText(Me.Project.FormatRegex(l_formatter))
    End Sub

#Region "Event Raiser Methods"
    ' Insert Method Declarations which Raise an Event Here
#End Region

#Region "Event Handlers"

    Private Sub Project_PropertyChanged(sender As Object, e As ComponentModel.PropertyChangedEventArgs)

        Select Case e.PropertyName

            Case "RegexHistory"
                OnPropertyChanged("RegexHistory")

        End Select

    End Sub

#End Region
#End Region

End Class
